﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Quester.Models;
using System.Web.Security;

namespace Quester.Controllers
{
    [Authorize(Roles = "Admin")]
    public class AdminController : Controller
    {
        Quester.Models.QuesterEntities ent = new QuesterEntities();

        //
        // GET: /Admin/

        public ActionResult Index()
        {
            return RedirectToAction("AdminList");
        }

        #region AdministratorsAction

        public ActionResult AdminList()
        {
            XListViewModel model = new XListViewModel();

            model.Title = "Адміністратори";
            
            string[] teacherNames = Roles.GetUsersInRole("admin");
            foreach (string t in teacherNames)
            {
                model.Items.Add(new Item() { Value = t, ID = (Guid)Membership.GetUser(t).ProviderUserKey });
            }

            model.ItemBtns.Add(new ActionBtn() { Action = "AdminDetail", Controller = "Admin", Title = "Деталі", Icon = "IconDetail.png", CssClass = "ActButton" });
            model.ItemBtns.Add(new ActionBtn() { Action = "AdminEdit", Controller = "Admin", Title = "Редагув.", Icon = "IconEdit.png", CssClass = "ActButton" });
            model.ItemBtns.Add(new ActionBtn() { Action = "DeleteUser", Controller = "Admin", Title = "Видалити", Icon = "IconDelete.png", CssClass = "ActButton" });

            model.CaptionBtns.Add(new ActionBtn(){Title = "Додати", Icon = "IconAdd.png", Action = "AdminCreate", Controller = "Admin", CssClass = "ActButton"});

            ViewBag.ListModel = model;
            return View();
        }

        public ActionResult StudentList()
        {
            XListViewModel model = new XListViewModel();

            model.Title = "Групи";
            var tmpList = from @group in ent.Group
                          select new Item() { ID = @group.GroupID, Value = @group.Kafedra + "/" + @group.GroupName};
            model.Items.AddRange(tmpList);
            model.ItemBtns.Add(new ActionBtn() { Action = "GroupDetail", Controller = "Admin", Title = "Деталі", Icon = "IconDetail.png", CssClass = "ActButton" });
            model.ItemBtns.Add(new ActionBtn() { Action = "GroupEdit", Controller = "Admin", Title = "Редагув.", Icon = "IconEdit.png", CssClass = "ActButton" });
            model.ItemBtns.Add(new ActionBtn() { Action = "DeleteGroup", Controller = "Admin", Title = "Видалити", Icon = "IconDelete.png", CssClass = "ActButton" });

            model.CaptionBtns.Add(new ActionBtn() { Title = "Додати", Icon = "IconAdd.png", Action = "AddGroup", Controller = "Admin", CssClass = "ActButton" });
            

            ViewBag.ListModel = model;
            return View();
        }

        public ActionResult AdminCreate()
        {
            return View();
        }

        [HttpPost]
        public ActionResult AdminCreate(AdminVModel model)
        {

            if (ModelState.IsValid)
            {
                // Attempt to register the user
                MembershipCreateStatus createStatus;
                Membership.CreateUser(model.Login, model.Password, model.EMail, null, null, true, null, out createStatus);

                if (createStatus == MembershipCreateStatus.Success)
                {
                    //Loger.WriteLog("Add new user: {0}, {1}", model.UserName, model.Role);
                    Roles.AddUserToRole(model.Login, "admin");
                    return RedirectToAction("Index");
                }
                else
                {
                    ModelState.AddModelError(createStatus.ToString(), "Error occured");
                }
            }

            return RedirectToAction("AdminList");
        }

        [HttpGet]
        public ActionResult AdminEdit(Guid Id)
        {

            AdminEditVModel adminVM = (from u in ent.aspnet_Users
                                   where u.UserId == Id
                                   from memRec in ent.aspnet_Membership
                                   where memRec.UserId == Id
                                   select new AdminEditVModel() 
                                   {
                                       EMail = memRec.Email,
                                       ID = Id,
                                       Login = u.UserName
                                   }).First<AdminEditVModel>();

            return View(adminVM);
        }

        [HttpPost]
        public ActionResult AdminEdit(AdminEditVModel model)
        {
            try
            {
                MembershipUser user = Membership.GetUser(model.Login);
                user.Email = model.EMail;
                Membership.UpdateUser(user);
            }
            catch (Exception e)
            {
                ViewBag.Message = e.Message;
                return RedirectToAction("AdminList");
            }

            TempData["Message"] = "Користувач збережений успішно";


            return RedirectToAction("AdminList");
        }


        [HttpGet]
        public ActionResult AdminDetail(Guid Id)
        {
            MembershipUser u = Membership.GetUser(Id);

            AdminDetailVModel model = new AdminDetailVModel()
            {
                ID = Id,
                UserName = u.UserName,
                EMail = u.Email,
                CreationDate = u.CreationDate
            };


            return View(model);


            
        }

        [HttpGet]
        public ActionResult DeleteUser(Guid Id)
        {
            UserDeleteVModel model = new UserDeleteVModel() { UserName = Membership.GetUser(Id).UserName };

            return View(model);
        }

        [HttpPost]
        public ActionResult DeleteUser(UserDeleteVModel model)
        {
            Guid GroupID = Guid.Empty;
            if (Roles.IsUserInRole(model.UserName, "admin"))
            {
                Membership.DeleteUser(model.UserName);
                ent.SaveChanges();
                return RedirectToAction("AdminList");
            }
            else if (Roles.IsUserInRole(model.UserName, "teacher"))
            {
                Guid userID = (Guid)Membership.GetUser(model.UserName).ProviderUserKey;
                ent.Teacher.DeleteObject(ent.Teacher.First(rec => rec.TeacherID == userID));
                Membership.DeleteUser(model.UserName);
                ent.SaveChanges();
                return RedirectToAction("TeacherList");
            }
            else if (Roles.IsUserInRole(model.UserName, "student"))
            {
                Guid userID = (Guid)Membership.GetUser(model.UserName).ProviderUserKey;
                GroupID = ent.Student.First(rec => rec.StudentID == userID).GroupID;
                ent.Student.DeleteObject(ent.Student.First(rec => rec.StudentID == userID));
                Membership.DeleteUser(model.UserName);
                ent.SaveChanges();
                return RedirectToAction("GroupDetail", new { ID = GroupID });
            }

            throw new HttpException(404, "user" + model.UserName + "not found.");
        }

        #endregion


        #region TeacherActions

        public ActionResult TeacherList()
        {
            XListViewModel model = new XListViewModel();

            model.Title = "Викладачі";

            string[] teacherNames = Roles.GetUsersInRole("teacher");
            foreach (string t in teacherNames)
            {
                Guid uID = (Guid)Membership.GetUser(t).ProviderUserKey;

                Teacher teach = (from rec in ent.Teacher
                                where rec.TeacherID == uID
                                select rec).First();
                string value = teach.LastName + " " + teach.Name[0] + "." + teach.FatherName[0] + ".";
                model.Items.Add(new Item() { Value = value, ID = (Guid)Membership.GetUser(t).ProviderUserKey });
            }


            model.ItemBtns.Add(new ActionBtn() { Action = "TeacherDetails", Controller = "Admin", Title = "Деталі", Icon = "IconDetail.png", CssClass = "ActButton" });
            model.ItemBtns.Add(new ActionBtn() { Action = "TeacherEdit", Controller = "Admin", Title = "Редагув.", Icon = "IconEdit.png", CssClass = "ActButton" });
            model.ItemBtns.Add(new ActionBtn() { Action = "DeleteUser", Controller = "Admin", Title = "Видалити", Icon = "IconDelete.png", CssClass = "ActButton" });

            model.CaptionBtns.Add(new ActionBtn() { Title = "Додати", Icon = "IconAdd.png", Action = "TeacherCreate", Controller = "Admin", CssClass = "ActButton" });

            ViewBag.ListModel = model;
            return View();
        }

        [HttpGet]
        public ActionResult TeacherCreate()
        {
            return View();
        }

        [HttpPost]
        public ActionResult TeacherCreate(TeacherCreateVModel model)
        {
            if (ModelState.IsValid)
            {
                // Attempt to register the user
                MembershipCreateStatus createStatus;
                
                MembershipUser user = Membership.CreateUser(model.Login, model.Password, model.EMail, null, null, true, null, out createStatus);

                if (createStatus == MembershipCreateStatus.Success)
                {
                    //Loger.WriteLog("Add new user: {0}, {1}", model.UserName, model.Role);
                    Roles.AddUserToRole(model.Login, "teacher");
                    model.ID = (Guid)user.ProviderUserKey;

                    ent.Teacher.AddObject(new Teacher() 
                    { 
                        FatherName = model.FatherName,
                        Kafedra = model.Kafedra,
                        LastName = model.LastName,
                        Name = model.Name,
                        TeacherID = model.ID
                    });

                    ent.SaveChanges();

                    return RedirectToAction("TeacherList");
                }
                else
                {
                    ModelState.AddModelError(createStatus.ToString(), "Error occured");
                }
            }

            return RedirectToAction("TeacherList");
        }

        [HttpGet]
        public ActionResult TeacherEdit(Guid ID)
        {
            MembershipUser userData = Membership.GetUser(ID);
            Teacher tc = ent.Teacher.First(rec => rec.TeacherID == ID);

            TeacherEditVModel model = new TeacherEditVModel() 
            {
                ID = ID,
                EMail = userData.Email,
                FatherName = tc.FatherName,
                Kafedra = tc.Kafedra,
                LastName = tc.LastName,
                Login = userData.UserName,
                Name = tc.Name
            };

            return View(model);
        }

        [HttpPost]
        public ActionResult TeacherEdit(TeacherEditVModel model)
        {
            if (ModelState.IsValid)
            {
                Teacher tc = ent.Teacher.First(rec => rec.TeacherID == model.ID);
                tc.Name = model.Name;
                tc.LastName = model.LastName;
                tc.Kafedra = model.Kafedra;
                tc.FatherName = model.FatherName;
                ent.SaveChanges();

                MembershipUser user = Membership.GetUser(model.ID);
                user.Email = model.EMail;
                Membership.UpdateUser(user);
            }
            else
            {
                return RedirectToAction("TeacherEdit", model);
            }

            return RedirectToAction("TeacherList");
        }


        [HttpGet]
        public ActionResult TeacherDetails(Guid ID)
        {
            MembershipUser userData = Membership.GetUser(ID);
            Teacher tc = ent.Teacher.First(rec => rec.TeacherID == ID);

            TeacherEditVModel model = new TeacherEditVModel()
            {
                ID = ID,
                EMail = userData.Email,
                FatherName = tc.FatherName,
                Kafedra = tc.Kafedra,
                LastName = tc.LastName,
                Login = userData.UserName,
                Name = tc.Name
            };

            return View(model);
        }

        #endregion

        #region Students

        public ActionResult AddGroup()
        {
            GroupVModel model = new GroupVModel() { GroupID = Guid.NewGuid()};
            return View(model);
        }

        [HttpPost]
        public ActionResult AddGroup(GroupVModel model)
        {
            if (ModelState.IsValid)
            {
                ent.Group.AddObject(new Group() { 
                    GroupName = model.GroupName,
                    GroupID = model.GroupID,
                    Kafedra = model.Kafedra,
                });
                ent.SaveChanges();
            }

            return RedirectToAction("StudentList");
        }

        [HttpGet]
        public ActionResult GroupDetail(Guid ID)
        {
            XListViewModel groupData = new XListViewModel();

            Group gr = ent.Group.First(rec => rec.GroupID == ID);

            groupData.Title = gr.Kafedra + " / " + gr.GroupName;

            groupData.Items = (from student in ent.Student
                              where student.GroupID == gr.GroupID
                              select new Item
                              { 
                                  ID = student.StudentID,
                                  Value = student.LastName + " " + student.Name + " " + student.FatherName 
                              }).OrderBy(item => item.Value).ToList();

            groupData.ItemBtns.Add(new ActionBtn() { Action = "StudentDetail", Controller = "Admin", Title = "Деталі", Icon = "IconDetail.png", CssClass = "ActButton" });
            groupData.ItemBtns.Add(new ActionBtn() { Action = "StudentEdit", Controller = "Admin", Title = "Редагув.", Icon = "IconEdit.png", CssClass = "ActButton" });
            groupData.ItemBtns.Add(new ActionBtn() { Action = "DeleteUser", Controller = "Admin", Title = "Видалити", Icon = "IconDelete.png", CssClass = "ActButton" });

            groupData.CaptionBtns.Add(new ActionBtn() { Title = "Назад", Icon = "IconBack.png", Action = "StudentList", Controller = "Admin", CssClass = "ActButton" });
            ActionBtn addBtn = new ActionBtn() { Title = "Додати", Icon = "IconAdd.png", Action = "AddStudent", Controller = "Admin", CssClass = "ActButton"};
            addBtn.Parametrs.Add("ID", gr.GroupID.ToString());
            groupData.CaptionBtns.Add(addBtn);

            ViewBag.ListModel = groupData;
            return View(new GroupVModel() { GroupID = gr.GroupID, GroupName = gr.GroupName, Kafedra = gr.Kafedra});

        }

        [HttpGet]
        public ActionResult GroupEdit(Guid ID)
        {
            Group gr = ent.Group.First(rec => rec.GroupID == ID);

            GroupVModel model = new GroupVModel() 
            {
                GroupID = gr.GroupID,
                GroupName = gr.GroupName,
                Kafedra = gr.Kafedra
            };
            return View(model);
        }

        [HttpPost]
        public ActionResult GroupEdit(GroupVModel model)
        {

            if (ModelState.IsValid)
            {
                Group gr = ent.Group.First(rec => rec.GroupID == model.GroupID);

                gr.GroupName = model.GroupName;
                gr.Kafedra = model.Kafedra;

                ent.SaveChanges();
            }
            else
            {
                return View(model);
            }

            return RedirectToAction("StudentList");
        }

        [HttpGet]
        public ActionResult DeleteGroup(Guid ID)
        {
            Group gr = ent.Group.First(rec => rec.GroupID == ID);
            GroupVModel model = new GroupVModel() 
            {
                GroupID = gr.GroupID,
                GroupName = gr.GroupName,
                Kafedra = gr.Kafedra
            };
            
            return View(model);
        }


        [HttpPost]
        public ActionResult DeleteGroup(GroupVModel model)
        {
            ent.Group.DeleteObject(ent.Group.First(rec => rec.GroupID == model.GroupID));
            List<Student> studList = (from st in ent.Student
                                      where st.GroupID == model.GroupID
                                          select st).ToList();

            foreach (Student s in studList)
            {
                Membership.DeleteUser(Membership.GetUser(s.StudentID).UserName);
                ent.Student.DeleteObject(s);
            }

            ent.SaveChanges();

            return RedirectToAction("StudentList");
        }

        [HttpGet]
        public ActionResult AddStudent(Guid Id)
        {
            StudentCreateVModel model = new StudentCreateVModel() { GroupID = Id, ID = Guid.Empty};

            return View(model);
        }

        [HttpPost]
        public ActionResult AddStudent(StudentCreateVModel model)
        {
            if (ModelState.IsValid)
            {
                // Attempt to register the user
                MembershipCreateStatus createStatus;

                MembershipUser user = Membership.CreateUser(model.Login, model.Password, model.EMail, null, null, true, null, out createStatus);

                if (createStatus == MembershipCreateStatus.Success)
                {
                    //Loger.WriteLog("Add new user: {0}, {1}", model.UserName, model.Role);
                    Roles.AddUserToRole(model.Login, "student");
                    model.ID = (Guid)user.ProviderUserKey;

                    ent.Student.AddObject(new Student()
                    {
                        FatherName = model.FatherName,
                        LastName = model.LastName,
                        Name = model.Name,
                        StudentID = model.ID,
                        GroupID = model.GroupID
                    });

                    ent.SaveChanges();

                    return RedirectToAction("GroupDetail", new { @ID = model.GroupID }); 
                }
                else if (createStatus == MembershipCreateStatus.DuplicateUserName)
                {
                    throw new HttpException(500, "Користувач з таким логіном уже існує. Придумайте інший");
                }
                else
                {
                    ModelState.AddModelError(createStatus.ToString(), "Error occured");
                }
            }

            return RedirectToAction("GroupDetail", new { @ID = model.GroupID }); 
        }

        public ActionResult StudentDetail(Guid ID)
        {
            MembershipUser userData = Membership.GetUser(ID);
            Student st = ent.Student.First(rec => rec.StudentID == ID);

            StudentEditVModel model = new StudentEditVModel()
            {
                ID = ID,
                EMail = userData.Email,
                FatherName = st.FatherName,
                LastName = st.LastName,
                Login = userData.UserName,
                Name = st.Name,
                GroupID = st.Group.GroupID,
                Group = st.Group.GroupName
            };

            return View(model);
        }

        [HttpGet]
        public ActionResult StudentEdit(Guid ID)
        {
            Student student = ent.Student.First(rec => rec.StudentID == ID);
            MembershipUser user = Membership.GetUser(ID);

            StudentEditVModel stModel = new StudentEditVModel()
            {
                ID = ID,
                Login = user.UserName,
                EMail = user.Email,
                
                Name = student.Name,
                FatherName = student.FatherName,
                LastName = student.LastName,
                GroupID = student.GroupID,
                Group = student.Group.GroupName
            };

            return View(stModel);

        }

        [HttpPost]
        public ActionResult StudentEdit(StudentEditVModel stModel)
        {
            if (ModelState.IsValid)
            {

                Student st = ent.Student.First(rec => rec.StudentID == stModel.ID);
                st.Name = stModel.Name;
                st.LastName = stModel.LastName;
                st.FatherName = stModel.FatherName;
                ent.SaveChanges();

                MembershipUser user = Membership.GetUser(stModel.ID);
                user.Email = stModel.EMail;
                Membership.UpdateUser(user);
            }
            else
            {
                return RedirectToAction("TeacherEdit", stModel);
            }

            return RedirectToAction("GroupDetail", new { ID = stModel.GroupID });
        }


        #endregion

        //TODO: Improve reset password logic
        [HttpGet]
        public ActionResult ResetPass(Guid ID)
        {
            
            return View();
        }

    }
}
